"""
工作流API路由

提供工作流管理和执行的API接口。
"""

from typing import Dict, List, Any, Optional
from datetime import datetime
from fastapi import APIRouter, HTTPException, Depends, Query, Path
from pydantic import BaseModel, Field

from ..workflows.workflow_manager import WorkflowManager
from ..workflows.workflow_types import WorkflowType, WorkflowStatus
from ..dependencies import get_workflow_manager


router = APIRouter(prefix="/workflows", tags=["workflows"])


# 请求模型
class WorkflowCreateRequest(BaseModel):
    """工作流创建请求模型"""
    workflow_type: str = Field(..., description="工作流类型")
    name: str = Field(..., description="工作流名称")
    description: Optional[str] = Field(None, description="工作流描述")
    parameters: Dict[str, Any] = Field(default_factory=dict, description="工作流参数")
    schedule: Optional[str] = Field(None, description="调度表达式")


class WorkflowExecuteRequest(BaseModel):
    """工作流执行请求模型"""
    parameters: Dict[str, Any] = Field(default_factory=dict, description="执行参数")
    priority: int = Field(default=5, ge=1, le=10, description="执行优先级")


class WorkflowUpdateRequest(BaseModel):
    """工作流更新请求模型"""
    name: Optional[str] = Field(None, description="工作流名称")
    description: Optional[str] = Field(None, description="工作流描述")
    parameters: Optional[Dict[str, Any]] = Field(None, description="工作流参数")
    schedule: Optional[str] = Field(None, description="调度表达式")
    status: Optional[str] = Field(None, description="工作流状态")


# 响应模型
class WorkflowInfo(BaseModel):
    """工作流信息模型"""
    workflow_id: str
    workflow_type: str
    name: str
    description: Optional[str] = None
    status: str
    created_at: datetime
    updated_at: Optional[datetime] = None
    last_execution: Optional[datetime] = None
    execution_count: int = 0
    success_rate: float = 0.0
    parameters: Dict[str, Any] = {}
    schedule: Optional[str] = None


class WorkflowExecution(BaseModel):
    """工作流执行模型"""
    execution_id: str
    workflow_id: str
    status: str
    started_at: datetime
    completed_at: Optional[datetime] = None
    duration: Optional[float] = None
    result: Optional[Dict[str, Any]] = None
    error_message: Optional[str] = None
    progress: float = 0.0


class WorkflowListResponse(BaseModel):
    """工作流列表响应模型"""
    workflows: List[WorkflowInfo]
    total: int
    page: int
    page_size: int


class WorkflowExecutionListResponse(BaseModel):
    """工作流执行列表响应模型"""
    executions: List[WorkflowExecution]
    total: int
    page: int
    page_size: int


# API端点
@router.get("/", response_model=WorkflowListResponse)
async def list_workflows(
    workflow_type: Optional[str] = Query(None, description="按类型筛选"),
    status: Optional[str] = Query(None, description="按状态筛选"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页大小"),
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowListResponse:
    """
    获取工作流列表
    
    Args:
        workflow_type: 类型筛选
        status: 状态筛选
        page: 页码
        page_size: 每页大小
        manager: 工作流管理器
        
    Returns:
        工作流列表响应
    """
    try:
        # 获取所有工作流
        all_workflows = await manager.list_workflows()
        
        # 应用筛选
        filtered_workflows = all_workflows
        if workflow_type:
            filtered_workflows = [w for w in filtered_workflows if w.workflow_type.value == workflow_type]
        if status:
            filtered_workflows = [w for w in filtered_workflows if w.status.value == status]
        
        # 分页
        total = len(filtered_workflows)
        start_idx = (page - 1) * page_size
        end_idx = start_idx + page_size
        page_workflows = filtered_workflows[start_idx:end_idx]
        
        # 构建响应
        workflow_infos = []
        for workflow in page_workflows:
            workflow_info = WorkflowInfo(
                workflow_id=workflow.workflow_id,
                workflow_type=workflow.workflow_type.value,
                name=workflow.name,
                description=workflow.description,
                status=workflow.status.value,
                created_at=workflow.created_at,
                updated_at=workflow.updated_at,
                execution_count=0,  # 实际应从统计获取
                success_rate=0.95,  # 实际应从统计获取
                parameters=workflow.parameters,
                schedule=workflow.schedule
            )
            workflow_infos.append(workflow_info)
        
        return WorkflowListResponse(
            workflows=workflow_infos,
            total=total,
            page=page,
            page_size=page_size
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取工作流列表失败: {str(e)}")


@router.get("/{workflow_id}", response_model=WorkflowInfo)
async def get_workflow(
    workflow_id: str = Path(..., description="工作流ID"),
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowInfo:
    """
    获取工作流详情
    
    Args:
        workflow_id: 工作流ID
        manager: 工作流管理器
        
    Returns:
        工作流信息
    """
    try:
        workflow = await manager.get_workflow(workflow_id)
        if not workflow:
            raise HTTPException(status_code=404, detail=f"工作流 {workflow_id} 不存在")
        
        return WorkflowInfo(
            workflow_id=workflow.workflow_id,
            workflow_type=workflow.workflow_type.value,
            name=workflow.name,
            description=workflow.description,
            status=workflow.status.value,
            created_at=workflow.created_at,
            updated_at=workflow.updated_at,
            execution_count=0,  # 实际应从统计获取
            success_rate=0.95,  # 实际应从统计获取
            parameters=workflow.parameters,
            schedule=workflow.schedule
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取工作流详情失败: {str(e)}")


@router.post("/", response_model=WorkflowInfo)
async def create_workflow(
    request: WorkflowCreateRequest,
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowInfo:
    """
    创建工作流
    
    Args:
        request: 创建请求
        manager: 工作流管理器
        
    Returns:
        工作流信息
    """
    try:
        # 验证工作流类型
        try:
            workflow_type = WorkflowType(request.workflow_type)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"无效的工作流类型: {request.workflow_type}")
        
        # 创建工作流
        workflow = await manager.create_workflow(
            workflow_type=workflow_type,
            name=request.name,
            description=request.description,
            parameters=request.parameters,
            schedule=request.schedule
        )
        
        return WorkflowInfo(
            workflow_id=workflow.workflow_id,
            workflow_type=workflow.workflow_type.value,
            name=workflow.name,
            description=workflow.description,
            status=workflow.status.value,
            created_at=workflow.created_at,
            execution_count=0,
            success_rate=0.0,
            parameters=workflow.parameters,
            schedule=workflow.schedule
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建工作流失败: {str(e)}")


@router.put("/{workflow_id}", response_model=WorkflowInfo)
async def update_workflow(
    workflow_id: str = Path(..., description="工作流ID"),
    request: WorkflowUpdateRequest = ...,
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowInfo:
    """
    更新工作流
    
    Args:
        workflow_id: 工作流ID
        request: 更新请求
        manager: 工作流管理器
        
    Returns:
        工作流信息
    """
    try:
        workflow = await manager.get_workflow(workflow_id)
        if not workflow:
            raise HTTPException(status_code=404, detail=f"工作流 {workflow_id} 不存在")
        
        # 更新工作流
        updated_workflow = await manager.update_workflow(
            workflow_id=workflow_id,
            name=request.name,
            description=request.description,
            parameters=request.parameters,
            schedule=request.schedule
        )
        
        return WorkflowInfo(
            workflow_id=updated_workflow.workflow_id,
            workflow_type=updated_workflow.workflow_type.value,
            name=updated_workflow.name,
            description=updated_workflow.description,
            status=updated_workflow.status.value,
            created_at=updated_workflow.created_at,
            updated_at=updated_workflow.updated_at,
            execution_count=0,
            success_rate=0.95,
            parameters=updated_workflow.parameters,
            schedule=updated_workflow.schedule
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新工作流失败: {str(e)}")


@router.delete("/{workflow_id}")
async def delete_workflow(
    workflow_id: str = Path(..., description="工作流ID"),
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> Dict[str, str]:
    """
    删除工作流
    
    Args:
        workflow_id: 工作流ID
        manager: 工作流管理器
        
    Returns:
        删除结果
    """
    try:
        workflow = await manager.get_workflow(workflow_id)
        if not workflow:
            raise HTTPException(status_code=404, detail=f"工作流 {workflow_id} 不存在")
        
        success = await manager.delete_workflow(workflow_id)
        if not success:
            raise HTTPException(status_code=500, detail="工作流删除失败")
        
        return {"message": f"工作流 {workflow_id} 已删除"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除工作流失败: {str(e)}")


@router.post("/{workflow_id}/execute", response_model=WorkflowExecution)
async def execute_workflow(
    workflow_id: str = Path(..., description="工作流ID"),
    request: WorkflowExecuteRequest = ...,
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowExecution:
    """
    执行工作流
    
    Args:
        workflow_id: 工作流ID
        request: 执行请求
        manager: 工作流管理器
        
    Returns:
        工作流执行信息
    """
    try:
        workflow = await manager.get_workflow(workflow_id)
        if not workflow:
            raise HTTPException(status_code=404, detail=f"工作流 {workflow_id} 不存在")
        
        # 执行工作流
        execution = await manager.execute_workflow(
            workflow_id=workflow_id,
            parameters=request.parameters
        )
        
        return WorkflowExecution(
            execution_id=execution.execution_id,
            workflow_id=execution.workflow_id,
            status=execution.status.value,
            started_at=execution.started_at,
            completed_at=execution.completed_at,
            duration=execution.duration,
            result=execution.result,
            error_message=execution.error_message,
            progress=execution.progress
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"执行工作流失败: {str(e)}")


@router.get("/{workflow_id}/executions", response_model=WorkflowExecutionListResponse)
async def get_workflow_executions(
    workflow_id: str = Path(..., description="工作流ID"),
    status: Optional[str] = Query(None, description="执行状态筛选"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页大小"),
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowExecutionListResponse:
    """
    获取工作流执行历史
    
    Args:
        workflow_id: 工作流ID
        status: 状态筛选
        page: 页码
        page_size: 每页大小
        manager: 工作流管理器
        
    Returns:
        执行历史列表
    """
    try:
        workflow = await manager.get_workflow(workflow_id)
        if not workflow:
            raise HTTPException(status_code=404, detail=f"工作流 {workflow_id} 不存在")
        
        # 获取执行历史
        executions = await manager.get_workflow_executions(
            workflow_id=workflow_id,
            status=status,
            limit=page_size,
            offset=(page - 1) * page_size
        )
        
        # 获取总数
        total = await manager.get_execution_count(workflow_id, status)
        
        # 构建响应
        execution_list = []
        for execution in executions:
            execution_info = WorkflowExecution(
                execution_id=execution.execution_id,
                workflow_id=execution.workflow_id,
                status=execution.status.value,
                started_at=execution.started_at,
                completed_at=execution.completed_at,
                duration=execution.duration,
                result=execution.result,
                error_message=execution.error_message,
                progress=execution.progress
            )
            execution_list.append(execution_info)
        
        return WorkflowExecutionListResponse(
            executions=execution_list,
            total=total,
            page=page,
            page_size=page_size
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取执行历史失败: {str(e)}")


@router.get("/executions/{execution_id}", response_model=WorkflowExecution)
async def get_execution(
    execution_id: str = Path(..., description="执行ID"),
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> WorkflowExecution:
    """
    获取执行详情
    
    Args:
        execution_id: 执行ID
        manager: 工作流管理器
        
    Returns:
        执行信息
    """
    try:
        execution = await manager.get_execution(execution_id)
        if not execution:
            raise HTTPException(status_code=404, detail=f"执行 {execution_id} 不存在")
        
        return WorkflowExecution(
            execution_id=execution.execution_id,
            workflow_id=execution.workflow_id,
            status=execution.status.value,
            started_at=execution.started_at,
            completed_at=execution.completed_at,
            duration=execution.duration,
            result=execution.result,
            error_message=execution.error_message,
            progress=execution.progress
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取执行详情失败: {str(e)}")


@router.post("/executions/{execution_id}/cancel")
async def cancel_execution(
    execution_id: str = Path(..., description="执行ID"),
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> Dict[str, str]:
    """
    取消执行
    
    Args:
        execution_id: 执行ID
        manager: 工作流管理器
        
    Returns:
        取消结果
    """
    try:
        execution = await manager.get_execution(execution_id)
        if not execution:
            raise HTTPException(status_code=404, detail=f"执行 {execution_id} 不存在")
        
        success = await manager.cancel_execution(execution_id)
        if not success:
            raise HTTPException(status_code=500, detail="取消执行失败")
        
        return {"message": f"执行 {execution_id} 已取消"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"取消执行失败: {str(e)}")


@router.get("/types/available")
async def get_available_workflow_types() -> List[Dict[str, str]]:
    """
    获取可用的工作流类型
    
    Returns:
        工作流类型列表
    """
    try:
        types = []
        for workflow_type in WorkflowType:
            types.append({
                "value": workflow_type.value,
                "name": workflow_type.name,
                "description": f"{workflow_type.value}工作流"
            })
        
        return types
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取工作流类型失败: {str(e)}")


@router.get("/status/summary")
async def get_workflow_status_summary(
    manager: WorkflowManager = Depends(get_workflow_manager)
) -> Dict[str, Any]:
    """
    获取工作流状态汇总
    
    Args:
        manager: 工作流管理器
        
    Returns:
        状态汇总信息
    """
    try:
        # 获取统计信息
        summary = await manager.get_status_summary()
        
        return {
            "total_workflows": summary.get("total_workflows", 0),
            "active_workflows": summary.get("active_workflows", 0),
            "running_executions": summary.get("running_executions", 0),
            "completed_today": summary.get("completed_today", 0),
            "failed_today": summary.get("failed_today", 0),
            "success_rate_today": summary.get("success_rate_today", 0.0),
            "avg_execution_time": summary.get("avg_execution_time", 0.0),
            "status_breakdown": summary.get("status_breakdown", {}),
            "type_breakdown": summary.get("type_breakdown", {})
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取状态汇总失败: {str(e)}")